package com.survivor.example;

import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.IntBuffer;

import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL;
import javax.microedition.khronos.opengles.GL10;

import com.survivor.opengl.R;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.opengl.GLU;
import android.opengl.GLUtils;
import android.opengl.GLSurfaceView.Renderer;

public class Lessone12Rendder implements Renderer {

	private int one = 0x10000;
	
	static float[][] boxcol=
	{
		{1.0f,0.0f,0.0f},{1.0f,0.5f,0.0f},{1.0f,1.0f,0.0f},{0.0f,1.0f,0.0f},{0.0f,1.0f,1.0f}
	};
	
	static float[][] topcol=
	{
		{.5f,0.0f,0.0f},{0.5f,0.25f,0.0f},{0.5f,0.5f,0.0f},{0.0f,0.5f,0.0f},{0.0f,0.5f,0.5f}
	};

	private int[] verCoord = {
	// Front
			-one, -one, one, one, -one, one, -one, one, one, one, one, one,

			// Back
			-one, -one, -one, -one, one, -one, one, -one, -one, one, one, -one,

			// Left

			-one, -one, one, -one, one, one, -one, -one, -one, -one, one, -one,

			// Right

			one, -one, one, one, -one, -one, one, one, one, one, one, -one,

			// Bottom

			-one, -one, one, -one, -one, -one, one, -one, one, one, -one, -one,

			// Top

			-one, one, one, one, one, one, -one, one, -one, one, one, -one

	};

	private IntBuffer verBuffer, texBuffer;

	private int[] texCoord = { 0, one, one, one, 0, 0, one, 0,

	one, one, one, 0, 0, one, one, one,

	one, one, one, 0, 0, one, 0, 0,

	0, one, one, one, 0, 0, one, 0,

	0, 0, 0, one, one, 0, one, one,

	0, one, one, one, 0, 0, one, 0 };

	private float rotX, rotY;

	private Bitmap bmp;

	private int[] textures = new int[1];

	private int yloop, xloop;

	public Lessone12Rendder(Context context) {
		// TODO Auto-generated constructor stub\
		bmp = BitmapFactory.decodeResource(context.getResources(),
				R.drawable.cube);

		verBuffer = makeIntBuffer(verCoord);
		texBuffer = makeIntBuffer(texCoord);
	}

	private IntBuffer makeIntBuffer(int[] src) {
		ByteBuffer bb = ByteBuffer.allocateDirect(src.length * 4);
		bb.order(ByteOrder.nativeOrder());

		IntBuffer ib = bb.asIntBuffer();
		ib.put(src);
		ib.position(0);

		return ib;
	}

	public void onDrawFrame(GL10 gl) {
		// TODO Auto-generated method stub
		doDraw(gl);
	}

	public void onSurfaceChanged(GL10 gl, int width, int height) {
		// TODO Auto-generated method stub
		if (height == 0)
			height = 1;
		gl.glViewport(0, 0, width, height); // Reset The Current Viewport
		gl.glMatrixMode(GL10.GL_PROJECTION); // Select The Projection Matrix
		gl.glLoadIdentity(); // Reset The Projection Matrix

		// Calculate The Aspect Ratio Of The Window
		GLU
				.gluPerspective(gl, 40.0f, (float) width / (float) height, .1f,
						100f);
		gl.glMatrixMode(GL10.GL_MODELVIEW); // Select The Modelview Matrix
		gl.glLoadIdentity();
	}

	public void onSurfaceCreated(GL10 gl, EGLConfig config) {
		// TODO Auto-generated method stub
		loadTexture(gl);

	}

	private void loadTexture(GL10 gl) {
		gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT, GL10.GL_NICEST);
		gl.glClearColor(0, 0, 0, 1f);

		gl.glEnable(GL10.GL_TEXTURE_2D);

		gl.glGenTextures(textures.length, textures, 0);
		int texture = textures[0];
		gl.glBindTexture(GL10.GL_TEXTURE_2D, texture);
		GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, bmp, 0);

		gl.glTexParameterx(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MAG_FILTER,
				GL10.GL_LINEAR);
		gl.glTexParameterx(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER,
				GL10.GL_LINEAR);

		gl.glEnable(GL10.GL_CULL_FACE);
		gl.glEnable(GL10.GL_DEPTH_TEST);
		gl.glClearDepthf(1f);
		gl.glDepthFunc(GL10.GL_LEQUAL);
		gl.glShadeModel(GL10.GL_SMOOTH);
	}

	private void doDraw(GL10 gl) {
		gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
		gl.glLoadIdentity();

		gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
		gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);

		gl.glEnable(GL10.GL_BLEND);
		gl.glBlendFunc(GL10.GL_SRC_ALPHA, GL10.GL_ONE);
		gl.glTexCoordPointer(2, GL10.GL_FIXED, 0, texBuffer);
		gl.glVertexPointer(3, GL10.GL_FIXED, 0, verBuffer);

		for (yloop = 1; yloop < 6; yloop++) {
			for (xloop = 0; xloop < yloop; xloop++) {
				gl.glLoadIdentity(); // Reset The View
				gl.glTranslatef(1.4f + ((float) xloop * 2.8f)
						- ((float) yloop * 1.4f),
						((6.0f - (float) yloop) * 2.4f) - 7.0f, -40.0f);
				gl.glRotatef(45.0f - (2.0f * yloop) + rotX, 1.0f, 0.0f, 0.0f);
				gl.glRotatef(45.0f + rotY, 0.0f, 1.0f, 0.0f);
				gl.glColor4f(boxcol[yloop - 1][0], boxcol[yloop - 1][1], boxcol[yloop - 1][2], 1f);
				drawBox(gl);
				gl.glColor4f(topcol[yloop - 1][0], topcol[yloop - 1][1], topcol[yloop - 1][2], 1f);
				drawTop(gl);
			}
		}

		gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
		gl.glDisableClientState(GL10.GL_TEXTURE_COORD_ARRAY);

	}

	private void drawBox(GL10 gl) {
		gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0, 4);
		gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 4, 4);
		gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 8, 4);
		gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 12, 4);
		gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 16, 4);
	}

	private void drawTop(GL10 gl) {
		gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 20, 4);
	}

}
